package cn.iocoder.yudao.module.shop.info.service;

import cn.iocoder.yudao.framework.business.address.service.AddressService;
import cn.iocoder.yudao.framework.business.eligibility.service.EligibilityApplyService;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.api.shop.info.dto.ShopInfoDTO;
import cn.iocoder.yudao.module.shop.category.pojo.po.ShopCategory;
import cn.iocoder.yudao.module.shop.info.dal.dataobject.ShopInfoDO;
import cn.iocoder.yudao.module.shop.info.vo.*;
import jakarta.annotation.Nullable;
import jakarta.validation.Valid;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;

/**
 * 店铺信息 Service 实现类
 *
 * @author 山野羡民（1032694760@qq.com）
 */
public interface ShopInfoService extends EligibilityApplyService<ShopInfoDO, AdminShopInfoVO, AppShopInfoSaveDTO, ShopInfoQueryDTO>, AddressService<ShopInfoDO> {

    /**
     * 获取商家用户编号
     *
     * @param id 店铺编号
     * @return 用户编号
     */
    Long getOwnerMemberUserId(Long id);

    /**
     * 判断是否店铺所有者，即是否商家
     *
     * @param memberUserId 用户编号
     * @return true/false
     */
    default boolean isOwnerByMemberUserId(Long memberUserId) {
        Long shopId = getShopIdByMemberUserId(memberUserId);
        return shopId != null && shopId > 0;
    }

    /**
     * 创建店铺信息
     *
     * @param reqVO 创建信息
     * @return 编号
     */
    Long createInfo(@Valid ShopInfoCreateVO reqVO);

    /**
     * 更新基础信息
     *
     * @param reqVO    更新信息
     */
    void updateInfo(@Valid ShopInfoBasicUpdateReqVO reqVO);

    /**
     * 更新基础信息
     *
     * @param userId   用户编号
     * @param userType 用户类型
     * @param reqVO    更新信息
     */
    void updateInfo(Long userId, Integer userType, @Valid ShopInfoBasicUpdateReqVO reqVO);

    /**
     * 更新行业类目
     *
     * @param reqVO 更新信息
     */
    void updateCategory(@Valid ShopCategoryUpdateReqVO reqVO);

    /**
     * 更新行业类目
     *
     * @param userId   用户编号
     * @param userType 用户类型
     * @param reqVO    更新信息
     */
    void updateCategory(Long userId, Integer userType, @Valid ShopCategoryUpdateReqVO reqVO);

    /**
     * 更新经营状态
     *
     * @param reqVO 更新信息
     */
    void updateStatus(ShopStatusUpdateReqVO reqVO);

    /**
     * 更新经营状态
     *
     * @param userId   用户编号
     * @param userType 用户类型
     * @param reqVO    更新信息
     */
    void updateStatus(Long userId, Integer userType, ShopStatusUpdateReqVO reqVO);

    /**
     * 更新开关
     *
     * @param reqVO 更新信息
     */
    void updateEnabled(ShopEnabledSaveVO reqVO);

    /**
     * 更新店铺套餐信息
     *
     * @param reqVO 更新信息
     */
    void updateEnterPackage(ShopEnterPackageUpdateReqVO reqVO);

    /**
     * 更新平台服务费比例
     *
     * @param reqVO 更新信息
     */
    void updateServiceFee(ShopServiceFeeUpdateReqVO reqVO);

    /**
     * 更新顾客可抵扣比例
     *
     * @param reqVO 更新信息
     */
    void updateDiscountPercent(ShopDiscountPercentUpdateReqVO reqVO);

    /**
     * 删除店铺信息
     *
     * @param id 编号
     */
    void deleteInfo(Long id);

    /**
     * 获得店铺信息
     *
     * @param id 编号
     * @return 店铺信息
     */
    @Nullable
    ShopInfoDO getInfo(Long id);

    /**
     * 获得店铺信息分页
     *
     * @param current 当前页
     * @param size 每页条数
     * @param reqVO 分页查询
     * @return 店铺信息分页
     */
    PageResult<ShopInfoDO> getInfoPage(Integer current, Integer size, ShopInfoQueryDTO reqVO);

    /**
     * 获得店铺信息列表
     *
     * @param ids 店铺编号集
     * @return 店铺信息列表
     */
    List<ShopInfoDO> getInfoList(Collection<Long> ids);

    /**
     * 获得店铺信息列表
     *
     * @param userId   用户编号
     * @param userType 用户类型
     * @return 店铺信息列表
     */
    List<ShopInfoDO> getInfoList(Long userId, Integer userType);

    /**
     * 获得店铺信息分页
     *
     * @param current 当前页
     * @param size 每页条数
     * @param reqVO 分页查询
     * @return 店铺信息分页
     */
    PageResult<ShopInfoDO> getInfoPage(Integer current, Integer size, AppShopInfoQueryDTO reqVO);

    /**
     * 搜索店铺简单资料列表
     *
     * @param keyword 关键词，店铺名称或店铺联系电话
     */
    List<ShopInfoDO> searchInfoList(String keyword);

    /**
     * 选择店铺简单资料列表
     *
     * @param ids    店铺编号
     */
    List<ShopInfoDO> pickInfoList(Collection<Long> ids);

    /**
     * 获得店铺简单资料列表
     *
     * @param status 店铺状态
     * @return 店铺简单资料列表
     */
    List<ShopInfoDO> getInfoList(@Nullable Integer status);

    /**
     * 通过店铺编号查询店铺信息
     *
     * @param ids    店铺编号
     * @param status 店铺状态
     * @return 店铺对象信息数组
     */
    List<ShopInfoDO> getInfoList(Collection<Long> ids, @Nullable Integer status);

    /**
     * 通过店铺编号查询店铺信息
     *
     * @param ids 店铺编号
     * @return 店铺对象信息键值对
     */
    default Map<Long, ShopInfoDTO> getInfoMap(Collection<Long> ids) {
        List<ShopInfoDO> list = getInfoList(ids, null);
        return convertMap(BeanUtils.toBean(list, ShopInfoDTO.class), ShopInfoDTO::getId);
    }

    /**
     * 获取店铺主营类目
     *
     * @param shopId 店铺编号
     */
    ShopCategory getShopCategory(Long shopId);

    /**
     * 按封禁获取店铺
     */
    Set<Long> getShopIdsByDisabled();

    /**
     * 按生活商圈获取店铺
     */
    Set<Long> getShopIdsByO2O();

    /**
     * 按行业类目获取店铺
     */
    Set<Long> getShopIdsByCategoryCode(String categoryCode);

    /**
     * 按行业类目获取店铺
     */
    Set<Long> getShopIdsByCategoryId(Long categoryId);

    /**
     * 按行政区域获取店铺
     */
    Set<Long> getShopIdsByCityCodes(Set<String> cityCodes);

    /**
     * 按行政区域获取店铺
     */
    Set<Long> getShopIdsByCountyCodes(Set<String> countyCodes);

    /**
     * 删除用户店铺，用户注销时用
     */
    void deleteInfoByMemberUserId(Long memberUserId);

    /**
     * 更新综合评分，当交易订单产品评价时触发
     *
     * @param id 店铺编号
     */
    void updateScoreWhenEvaluation(Long id);

    /**
     * 获取店铺信息
     *
     * @param memberUserId 用户编号
     */
    ShopInfoDO getShopInfoByMemberUserId(Long memberUserId);

    /**
     * 获取店铺信息
     *
     * @param adminUserId 用户编号
     */
    ShopInfoDO getShopInfoByAdminUserId(Long adminUserId);

    /**
     * 获取店铺编号
     *
     * @param memberUserId 用户编号
     */
    Long getShopIdByMemberUserId(Long memberUserId);

    /**
     * 获取店铺编号
     *
     * @param adminUserId 用户编号
     */
    Long getShopIdByAdminUserId(Long adminUserId);

    /**
     * 获取店铺服务费比例
     *
     * @param id 店铺编号
     */
    double getServiceFeePercent(Long id);

}
